﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using TrainGame.Model;

namespace TrainGame.AI.TileLay
{
	/// <summary>
	/// Help another of the companies owned by this president
	/// </summary>
	internal class HelpOtherCompanyTileGoal : TileLayGoal
	{
		static private TileLayGoal[] s_tileLayGoals =
		{
			new HeadForDestinationTileGoal(),
			new ImproveCurrentRoutesTileGoal(),
			//new ImproveRoutesForPlannedTrainsTileGoal(),
		};

		public override string GetName(PublicCompany company)
		{
			string companyName = (CompanyToHelp != null) ? CompanyToHelp.Name : "";
			string goalName = (GoalToHelp != null) ? GoalToHelp.GetName(CompanyToHelp) : "";
			return string.Format ("HelpOtherCompany {0} {1}", companyName, goalName);
		}

		private List<PublicCompany> OurOtherCompanies;
		private PublicCompany CompanyToHelp;
		private TileLayGoal GoalToHelp;

		/// <summary>
		///  get need - fills in OurOtherCompanies, CompanyToHelp, and GoalToHelp
		/// </summary>
		protected override int ComputeNeed(Gameboard gameboard, PublicCompany company, Dictionary<string, GameboardHex> runToHexes, AiMoveConfig config)
		{
			OurOtherCompanies = GetPlayersOtherCompanies(company.Owner, company);
			CompanyToHelp = null;
			GoalToHelp = null;
			int highestNeed = 0;

			foreach (PublicCompany otherCompany in OurOtherCompanies)
			{
				foreach (TileLayGoal goal in s_tileLayGoals)
				{
					// need/3 so our needs override other companies normally
					int need = goal.ComputeNeedValue(gameboard, otherCompany, runToHexes, config) / 3;
					if (need > highestNeed)
					{
						highestNeed = need;
						CompanyToHelp = otherCompany;
						GoalToHelp = goal;
					}
				}
			}
			this.Need = highestNeed;
			return highestNeed;
		}

		static private List<PublicCompany> GetPlayersOtherCompanies(Player player, PublicCompany notThisCompany)
		{
			List<PublicCompany> companies = new List<PublicCompany>();
			Game game = player.Game;
			foreach (PublicCompany company in game.PublicCompanies)
			{
				if ((company.Owner == player) && (company.Name != notThisCompany.Name))
					companies.Add(company);
			}
			return companies;
		}

		/// <summary>
		/// get tile lay - reads OurOtherCompanies, CompanyToHelp, and GoalToHelp
		/// </summary>
		internal override List<AiTileLay> ComputeTileLays(Stopwatch watch, TimeSpan timeLimit, Gameboard gameboard, PublicCompany company, List<AiTileLay> tileLays, Dictionary<string, GameboardHex> runToHexes, Dictionary<string, GameboardHex> tileLayHexes, AiMoveConfig config)
		{
			// impersonate the other company using our possible tile lays
			return GoalToHelp.ComputeTileLays(watch, timeLimit, gameboard, CompanyToHelp, tileLays, runToHexes, tileLayHexes, config);
		}
	}
}
